home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2001 May / may_2001.iso / intercd / root / Multimedia / ^DivX_Article / virtualdub / VirtualDub-source-1_4d / Init.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-03-20  |  11.6 KB  |  524 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    Copyright (C) 1998-2001 Avery Lee
  3. //
  4. //    This program is free software; you can redistribute it and/or modify
  5. //    it under the terms of the GNU General Public License as published by
  6. //    the Free Software Foundation; either version 2 of the License, or
  7. //    (at your option) any later version.
  8. //
  9. //    This program is distributed in the hope that it will be useful,
  10. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. //    GNU General Public License for more details.
  13. //
  14. //    You should have received a copy of the GNU General Public License
  15. //    along with this program; if not, write to the Free Software
  16. //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. #include "VirtualDub.h"
  19.  
  20. #include <crtdbg.h>
  21. #include <windows.h>
  22. #include <commctrl.h>
  23. #include <vfw.h>
  24. #include <shellapi.h>
  25.  
  26. #include "resource.h"
  27. #include "job.h"
  28. #include "oshelper.h"
  29. #include "prefs.h"
  30. #include "auxdlg.h"
  31. #include "error.h"
  32. #include "gui.h"
  33. #include "filters.h"
  34. #include "command.h"
  35. #include "ddrawsup.h"
  36. #include "script.h"
  37. #include "tls.h"
  38. #include "crash.h"
  39.  
  40. #include "ClippingControl.h"
  41. #include "PositionControl.h"
  42. #include "LevelControl.h"
  43. #include "HexViewer.h"
  44. #include "MRUList.h"
  45.  
  46. ///////////////////////////////////////////////////////////////////////////
  47.  
  48. extern void InitBuiltinFilters();
  49.  
  50. ///////////////////////////////////////////////////////////////////////////
  51.  
  52. extern LONG __stdcall CrashHandler(struct _EXCEPTION_POINTERS *ExceptionInfo);
  53. extern void FreeCompressor(COMPVARS *pCompVars);
  54. extern LONG APIENTRY MainWndProc( HWND hWnd, UINT message, UINT wParam, LONG lParam);
  55. extern void DetectDivX();
  56.  
  57. bool InitApplication(HINSTANCE hInstance);
  58. bool InitInstance( HANDLE hInstance, int nCmdShow);
  59. void ParseCommandLine(char *lpCmdLine);
  60.  
  61. ///////////////////////////////////////////////////////////////////////////
  62.  
  63. static BOOL compInstalled;    // yuck
  64.  
  65. extern "C" unsigned long version_num;
  66.  
  67. extern HINSTANCE    g_hInst;
  68. extern HWND            g_hWnd;
  69. extern HMENU        hMenuNormal, hMenuDub, g_hmenuDisplay;
  70. extern HACCEL        g_hAccelMain;
  71. extern MRUList        *mru_list;
  72.  
  73. extern char g_msgBuf[128];
  74. extern char g_szFile[MAX_PATH];
  75.  
  76. static const char szAppName[]="VirtualDub";
  77. extern const char g_szError[];
  78.  
  79. bool g_fWine = false;
  80.  
  81. ///////////////////////////////////////////////////////////////////////////
  82.  
  83. #if 1
  84.  
  85. void crash() {
  86.     __try {
  87.         __asm xor ebx,ebx
  88.         __asm mov eax,dword ptr [ebx]
  89.         __asm mov dword ptr [ebx],eax
  90.     } __except(CrashHandler((EXCEPTION_POINTERS*)_exception_info())) {
  91.     }
  92. }
  93. #endif
  94.  
  95. bool Init(HINSTANCE hInstance, LPSTR lpCmdLine, int nCmdShow) {
  96.  
  97. #ifdef _DEBUG
  98.     _CrtSetDbgFlag(_CRTDBG_CHECK_ALWAYS_DF);
  99. #endif
  100.  
  101.     // setup crash trap
  102.  
  103.     SetUnhandledExceptionFilter(CrashHandler);
  104.  
  105.     // initialize globals
  106.  
  107.     g_hInst = hInstance;
  108.  
  109.     // initialize TLS for main thread
  110.  
  111.     InitThreadData("Main thread");
  112.  
  113.     // prep system stuff
  114.  
  115.     VDCHECKPOINT;
  116.  
  117.     AVIFileInit();
  118.  
  119.     // initialize filters, job system, MRU list, help system
  120.  
  121.     InitBuiltinFilters();
  122.  
  123.     if (!InitJobSystem())
  124.         return FALSE;
  125.  
  126.     if (!(mru_list = new MRUList(4, "MRU List"))) return false;
  127.  
  128.     HelpSetPath();
  129.  
  130.     LoadPreferences();
  131.  
  132.     // initialize interface
  133.  
  134.     VDCHECKPOINT;
  135.  
  136.     if (!InitApplication(hInstance))
  137.             return (FALSE);              
  138.  
  139.     // display welcome requester
  140.  
  141.     Welcome();
  142.  
  143.     // Create the main window.
  144.  
  145.     if (!InitInstance(hInstance, nCmdShow))
  146.         return (FALSE);
  147.  
  148.     DragAcceptFiles(g_hWnd, TRUE);
  149.  
  150.     // Autoload filters.
  151.  
  152.     VDCHECKPOINT;
  153.     {
  154.         int f, s;
  155.  
  156.         s = FilterAutoloadModules(f);
  157.  
  158.         if (s || f)
  159.             guiSetStatus("Autoloaded %d filters (%d failed).", 255, s, f);
  160.     }
  161.  
  162.     // Detect DivX.
  163.  
  164.     DetectDivX();
  165.  
  166.     // attempt to initialize DirectDraw 2, if we have it
  167.  
  168. #ifdef ENABLE_DIRECTDRAW_SUPPORT
  169.     EnableMenuItem(GetMenu(g_hWnd),ID_OPTIONS_ENABLEDIRECTDRAW, (DDrawDetect() ? (MF_BYCOMMAND|MF_ENABLED) : (MF_BYCOMMAND|MF_GRAYED)));
  170. #endif
  171.  
  172.     _RPT1(0,"[%s]\n",lpCmdLine);
  173.  
  174.     while(isspace(*lpCmdLine)) ++lpCmdLine;
  175.  
  176.     if (*lpCmdLine=='&') {
  177.         ICRemove(ICTYPE_VIDEO, 'TSDV', 0);
  178.         compInstalled = ICInstall(ICTYPE_VIDEO, 'TSDV', (LPARAM)(lpCmdLine+1), 0, ICINSTALL_DRIVER);
  179.  
  180.         if (!compInstalled)
  181. //            MessageBox(NULL, "Warning: Unable to load compressor.", szError, MB_OK);
  182.             MyICError("External compressor", compInstalled).post(NULL, g_szError);
  183.         else
  184.             MessageBox(NULL, "External compressor loaded.", "Cool!", MB_OK);
  185.     } else if (*lpCmdLine == ':') {
  186.         if (lpCmdLine[1] && lpCmdLine[2] && lpCmdLine[3] && lpCmdLine[4]) {
  187.             DWORD fccHandler = *(DWORD *)(lpCmdLine+1);
  188.             HMODULE hmodVC = LoadLibrary(lpCmdLine+5);
  189.  
  190.             if (hmodVC) {
  191.                 DWORD pEntry = (DWORD)GetProcAddress(hmodVC, "DriverProc");
  192.  
  193.                 if (pEntry) {
  194.                     BOOL b = ICInstall(ICTYPE_VIDEO, fccHandler, (LPARAM)pEntry, 0, ICINSTALL_FUNCTION);
  195.  
  196.                     if (b)
  197.                         MessageBox(NULL, "External compressor loaded as function.", "Cool!", MB_OK);
  198.                 }
  199.             }
  200.         }
  201.     } else if (*lpCmdLine == '!') {
  202.         try {
  203.             FilterLoadModule(lpCmdLine+1);
  204.  
  205.             guiSetStatus("Loaded external filter module: %s", 255, lpCmdLine+1);
  206.         } catch(MyError e) {
  207.             e.post(g_hWnd, g_szError);
  208.         }
  209.     } else
  210.         ParseCommandLine(lpCmdLine);
  211.  
  212.     // All done!
  213.  
  214.     VDCHECKPOINT;
  215.  
  216.     return true;
  217. }
  218.  
  219. ///////////////////////////////////////////////////////////////////////////
  220.  
  221. void Deinit() {
  222.     FilterInstance *fa;
  223.  
  224.     VDCHECKPOINT;
  225.  
  226.     DragAcceptFiles(g_hWnd, FALSE);
  227.  
  228.     filters.DeinitFilters();
  229.  
  230.     VDCHECKPOINT;
  231.  
  232.     while(fa = (FilterInstance *)g_listFA.RemoveHead()) {
  233.         fa->Destroy();
  234.     }
  235.  
  236.     VDCHECKPOINT;
  237.  
  238.     FilterUnloadAllModules();
  239.  
  240.     VDCHECKPOINT;
  241.  
  242.     CloseAVI();
  243.     CloseWAV();
  244.  
  245.     VDCHECKPOINT;
  246.  
  247.     CloseJobWindow();
  248.     DeinitJobSystem();
  249.  
  250.     VDCHECKPOINT;
  251.  
  252.     if (g_Vcompression.dwFlags & ICMF_COMPVARS_VALID)
  253.         FreeCompressor(&g_Vcompression);
  254.  
  255.     if (compInstalled)
  256.         ICRemove(ICTYPE_VIDEO, 'TSDV', 0);
  257.  
  258.  
  259.     // deinitialize DirectDraw2
  260.  
  261.     VDCHECKPOINT;
  262.     DDrawDeinitialize();
  263.  
  264.     AVIFileExit();
  265.  
  266.     delete mru_list;
  267.  
  268.     _CrtCheckMemory();
  269.  
  270.     _CrtDumpMemoryLeaks();
  271.  
  272.     VDCHECKPOINT;
  273. }
  274.  
  275. ///////////////////////////////////////////////////////////////////////////
  276.  
  277. bool InitApplication(HINSTANCE hInstance) {
  278.     WNDCLASS  wc;
  279.  
  280.     // register controls
  281.  
  282.     InitCommonControls();
  283.  
  284.     if (!RegisterClippingControl()) return false;
  285.     if (!RegisterPositionControl()) return false;
  286.     if (!RegisterLevelControl()) return false;
  287.     if (!RegisterHexViewer()) return false;
  288.  
  289.     // Load menus.
  290.  
  291.     if (!(hMenuNormal    = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_MAIN_MENU    )))) return false;
  292.     if (!(hMenuDub        = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_DUB_MENU     )))) return false;
  293.     if (!(g_hmenuDisplay= LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_DISPLAY_MENU )))) return false;
  294.  
  295.     // Load accelerators.
  296.  
  297.     if (!(g_hAccelMain = LoadAccelerators(g_hInst, MAKEINTRESOURCE(IDR_IDLE_KEYS)))) return false;
  298.  
  299.     wc.style = CS_OWNDC;
  300.     wc.lpfnWndProc = (WNDPROC)MainWndProc;
  301.     wc.cbClsExtra = 0;
  302.     wc.cbWndExtra = 0;
  303.     wc.hInstance = hInstance;
  304.     wc.hIcon = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_VIRTUALDUB));
  305.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  306.     wc.hbrBackground = (HBRUSH)(COLOR_3DFACE+1); //GetStockObject(LTGRAY_BRUSH); 
  307.     wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAIN_MENU);
  308.     wc.lpszClassName = szAppName;
  309.  
  310.     return !!RegisterClass(&wc);
  311. }
  312.  
  313. ///////////////////////////////////////////////////////////////////////////
  314.  
  315. bool InitInstance( HANDLE hInstance, int nCmdShow) {
  316.     char buf[256];
  317.  
  318.     LoadString(g_hInst, IDS_TITLE_INITIAL, g_msgBuf, sizeof g_msgBuf);
  319.  
  320.     wsprintf(buf, g_msgBuf, version_num,
  321. #ifdef _DEBUG
  322.         "debug"
  323. #else
  324.         "release"
  325. #endif
  326.         );
  327.  
  328.     // Create a main window for this application instance. 
  329.     g_hWnd = CreateWindow(
  330.         szAppName,
  331.         "",
  332.         WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN,            // Window style.
  333.         CW_USEDEFAULT,                  // Default horizontal position.
  334.         CW_USEDEFAULT,                  // Default vertical position.
  335.         CW_USEDEFAULT,                  // Default width.
  336.         CW_USEDEFAULT,                  // Default height.
  337.         NULL,                           // Overlapped windows have no parent.
  338.         NULL,                           // Use the window class menu.
  339.         g_hInst,                        // This instance owns this window.
  340.         NULL                            // Pointer not needed.
  341.     );
  342.  
  343.     // If window could not be created, return "failure".
  344.     if (!g_hWnd)
  345.         return (FALSE);
  346.  
  347.     // Make the window visible; update its client area; and return "success".
  348.     ShowWindow(g_hWnd, nCmdShow);  
  349.     UpdateWindow(g_hWnd);          
  350.  
  351.     SendMessage(g_hWnd, WM_SETTEXT, 0, (LPARAM)buf);
  352.  
  353.     return (TRUE);               
  354.  
  355. }
  356.  
  357. ///////////////////////////////////////////////////////////////////////////
  358.  
  359. void ParseCommandLine(char *lpCmdLine) {
  360.     char *const cmdline = strdup(lpCmdLine);
  361.     if (!cmdline) return;
  362.  
  363.     char *token, *s;
  364.     static const char *seps = " \t\n\r";
  365.     bool fExitOnDone = false;
  366.  
  367.     // parse cmdline looking for switches
  368.     //
  369.     //    /s                        run script
  370.     //    /c                        clear job list
  371.     //    /b<srcdir>,<dstdir>        add directory batch process to job list
  372.     //    /r                        run job list
  373.     //    /x                        exit when jobs complete
  374.     //    /h                        disable crash handler
  375.  
  376.     s = cmdline;
  377.     g_szFile[0] = 0;
  378.  
  379.     try {
  380.         while(*s) {
  381.             char *t;
  382.             bool quoted = false;
  383.             bool restore_slash = false;
  384.  
  385.             while(isspace(*s))
  386.                 ++s;
  387.  
  388.             if (!*s) break;
  389.  
  390.             token = s;
  391.  
  392.             if (*s == '"') {
  393.                 s = ++token;
  394.  
  395.                 while(*s && *s!='"')
  396.                     ++s;
  397.  
  398.                 if (*s)
  399.                     *s++=0;
  400.  
  401.             } else {
  402.                 if (*s == '/')
  403.                     ++s;
  404.  
  405.                 while(*s && (quoted || (!isspace(*s) && *s!='/'))) {
  406.                     if (*s == '"')
  407.                         quoted = !quoted;
  408.  
  409.                     ++s;
  410.                 }
  411.  
  412.                 if (*s) {
  413.                     restore_slash = (*s=='/');
  414.                     *s++ = 0;
  415.                 }
  416.             }
  417.  
  418.             _RPT1(0,"token [%s]\n", token);
  419.  
  420.             if (*token == '-' || *token == '/') {
  421.                 switch(token[1]) {
  422.                 case 's':
  423.  
  424.                     t = token + 2;
  425.                     if (*t == '"') {
  426.                         ++t;
  427.                         while(*t && *t != '"')
  428.                             ++t;
  429.                         *t = 0;
  430.  
  431.                         t = token+3;
  432.                     }
  433.  
  434.                     JobLockDubber();
  435.                     RunScript(t);
  436.                     JobUnlockDubber();
  437.                     break;
  438.                 case 'c':
  439.                     JobClearList();
  440.                     break;
  441.                 case 'r':
  442.                     JobRunList();
  443.                     break;
  444.                 case 'x':
  445.                     fExitOnDone = true;
  446.                     break;
  447.                 case 'h':
  448.                     SetUnhandledExceptionFilter(NULL);
  449.                     break;
  450.                 case 'b':
  451.                     {
  452.                         char *arg1, *arg2;
  453.  
  454.                         // dequote first token
  455.  
  456.                         t = token+2;
  457.  
  458.                         if (*t == '"') {
  459.                             arg1 = ++t;
  460.                             while(*t && *t!='"')
  461.                                 ++t;
  462.  
  463.                             if (*t)
  464.                                 *t++ = 0;
  465.                         } else {
  466.                             arg1 = t;
  467.                             while(*t && *t!=',')
  468.                                 ++t;
  469.                         }
  470.  
  471.                         if (*t++ != ',')
  472.                             throw "Command line error: /b format is /b<src_dir>,<dst_dir>";
  473.  
  474.                         // dequote second token
  475.  
  476.                         arg2 = t;
  477.  
  478.                         if (*t == '"') {
  479.                             arg2 = ++t;
  480.  
  481.                             while(*t && *t!='"')
  482.                                 ++t;
  483.  
  484.                             if (*t)
  485.                                 *t++ = 0;
  486.                         } else {
  487.                             while(*t && *t!=',')
  488.                                 ++t;
  489.                         }
  490.  
  491.                         if (!*arg2)
  492.                             throw "Command line error: /b format is /b<src_dir>,<dst_dir>";
  493.  
  494.                         JobAddBatchDirectory(arg1, arg2);
  495.                     }
  496.                     break;
  497.                 case 'w':
  498.                     g_fWine = true;
  499.                     break;
  500.  
  501.             case 'f':
  502.                if (!stricmp(token+2, "sck"))
  503.                   __asm int 3;
  504.                break;
  505.  
  506.                 }
  507.             } else
  508.                 strcpy(g_szFile, token);
  509.  
  510.             if (restore_slash)
  511.                 *--s='/';
  512.         }
  513.     } catch(char *s) {
  514.         MessageBox(NULL, s, g_szError, MB_OK);
  515.     }
  516.  
  517.     free(cmdline);
  518.  
  519.     if (fExitOnDone) {
  520.         Deinit();
  521.         ExitProcess(0);
  522.     }
  523. }
  524.